package com.lz.ub.hm

import com.felhr.usbserial.UsbSerialDevice
import com.lz.ub.Logger

/**
 * @author you
 * 蓝牙指令处理器
 */
internal abstract class UBCommand(
    private val serialPort: UsbSerialDevice,
    internal val connectTimeout: Long,
) : UBCommandCallback {

    companion object {
        const val TAG = "UBCommand"
    }

    //连接器
    private val connection by lazy { UBConnection(this) }

    //指令回调
    private var ubCallback: UBCallback? = null

    fun close() {
        serialPort.close()
        connection.clear()
    }

    //当前是否可发指令
    fun isAvailable(): Boolean = connection.isAvailable()

    //连接, 要先判断是否可发指令
    fun connect(devices: List<UBDevice>, callback: UBCallback?): Boolean {
        if (connection.pushConnection(devices)) {
            this.ubCallback = callback
            this.ubCallback?.onStart()
            return true
        }
        callback?.onComplete()
        return false
    }

    fun connect(device: UBDevice, callback: UBCallback?): Boolean {
        if (connection.pushConnection(device)) {
            this.ubCallback = callback
            this.ubCallback?.onStart()
            return true
        }
        callback?.onComplete()
        return false
    }

    //断开连接, 要先判断是否可发指令
    fun disconnect(devices: List<UBDevice>, callback: UBCallback?): Boolean {
        if (connection.pushDisconnection(devices)) {
            this.ubCallback = callback
            this.ubCallback?.onStart()
            return true
        }
        callback?.onComplete()
        return false
    }

    fun disconnect(device: UBDevice, callback: UBCallback?): Boolean {
        if (connection.pushDisconnection(device)) {
            this.ubCallback = callback
            this.ubCallback?.onStart()
            return true
        }
        callback?.onComplete()
        return false
    }

    fun pushCommand(command: String): Boolean = write(command)

    fun write(command: String): Boolean = try {
        Logger.d(TAG, "write command $command <<====")
        serialPort.write(command.toByteArray())
        true
    } catch (_: Exception) {
        false
    }

    fun complete() {
        ubCallback?.onComplete()
        ubCallback = null
    }

    //处理服务连接状态, 有可能连接超时的又打开了,重新连接因此link不在此次请求中
    fun handleServiceStateChanged(status: Int, link: Int): Boolean = connection.serviceCallback(status, link)

    fun reset() {
        connection.clear()
    }

    override fun onConnectedStateChanged(isConn: Boolean, status: Int) {
        connection.connectCallback(isConn, status)
    }

    override fun onPropertyStateChanged(status: Int) {
        connection.propertyCallback(status)
    }

    override fun onWrite(status: Int) {
        Logger.i(TAG, "UBCommand onWrite $status")
    }

    override fun onError(err: String) {
        if (connection.isExecuting()) connection.errorCallback()
    }
}